package com.ccx.demo.business.common.controller;

import com.ccx.demo.config.ScheduleConfiguration;
import com.ccx.demo.config.init.AppConfig;
import com.support.mvc.entity.base.Result;
import com.utils.IAutoTask;
import com.utils.enums.Code;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.constraints.Pattern;
import java.util.Optional;

/**
 * 定时任务
 *
 * @author 谢长春 2017年7月21日 上午10:19:28
 */
@Controller
@Secured("ROLE_ADMIN")
@RequestMapping("/auto-task")
@Slf4j
@RequiredArgsConstructor
public class AutoTaskController {

    private final ApplicationContext applicationContext;
    private final AppConfig appConfig;
    @Autowired(required = false)
    private ScheduleConfiguration scheduleConfiguration;

    /**
     * 触发定时任务集合中指定下标的定时任务， 前提是定时任务开关处于开启状态
     *
     * @param beanName int {@link ScheduleConfiguration#getServices()} 集合下标
     * @return {@link Result}
     */
    @PostMapping("/call/{beanName}")
    @ResponseBody
    public Result<Void> call(@PathVariable final String beanName) {
        return new Result<Void>().call(() -> {
            Code.A00002.assertNonNull(scheduleConfiguration, "定时任务总开关处于关闭状态");
            final IAutoTask.AutoTaskItem task = scheduleConfiguration.getServices().get(beanName);
            Code.A00002.assertHasTrue(task.isEnabled(), "[%s:%s] 定时任务开关处于关闭状态", beanName, task.getComment());
            applicationContext.getBean(Optional.ofNullable(task.getName()).orElse(beanName), IAutoTask.class).call(null);
        });
    }

    /**
     * 触发定时任务集合中指定下标的定时任务， 前提是定时任务开关处于开启状态
     *
     * @param beanName int {@link ScheduleConfiguration#getServices()} 集合下标
     * @param args     String {@link String} 日期格式： yyyyMMdd 或 yyyyMMddHHmmss
     * @return {@link Result}
     */
    @PostMapping("/call/{beanName}/{args}")
    @ResponseBody
    public Result<Void> call(@PathVariable final String beanName,
                             @PathVariable @Pattern(regexp = "\\d{8,}") final String args) {
        return new Result<Void>().call(() -> {
            Code.A00002.assertNonNull(scheduleConfiguration, "定时任务总开关处于关闭状态");
            final IAutoTask.AutoTaskItem task = scheduleConfiguration.getServices().get(beanName);
            Code.A00002.assertHasTrue(task.isEnabled(), "[%s:%s] 定时任务开关处于关闭状态", beanName, task.getComment());
            applicationContext.getBean(Optional.ofNullable(task.getName()).orElse(beanName), IAutoTask.class).call(args);
        });
    }
}
